/*
 * 立方体にテクスチャを貼るテスト
 */
#include	<system.h>
#include	<v93.h>
#include	<nt.h>
#include	<farl.h>
#include	<asl.h>
#include	<agl.h>
#include	<common.h>
#include	<libm.h>
#include	<pio.h>

#define	NULL		0

#define	MAXCUBE		3
#define	TRIANGLE_NUMBER	12		// ポリゴン数

unsigned short  buf[163840];
unsigned short	colortable[512];
unsigned short	cube_buf[MAXCUBE][1024];

// 頂点の座標
float	cube_vert[TRIANGLE_NUMBER*3][3] = {
	{ -0.3,  0.3,  0.3 }, { -0.3, -0.3,  0.3 }, {  0.3,  0.3,  0.3 },
	{  0.3,  0.3,  0.3 }, { -0.3, -0.3,  0.3 }, {  0.3, -0.3,  0.3 },
	{  0.3,  0.3,  0.3 }, {  0.3, -0.3,  0.3 }, {  0.3,  0.3, -0.3 },
	{  0.3,  0.3, -0.3 }, {  0.3, -0.3,  0.3 }, {  0.3, -0.3, -0.3 },
	{  0.3,  0.3, -0.3 }, {  0.3, -0.3, -0.3 }, { -0.3,  0.3, -0.3 },
	{ -0.3,  0.3, -0.3 }, {  0.3, -0.3, -0.3 }, { -0.3, -0.3, -0.3 },
	{ -0.3,  0.3, -0.3 }, { -0.3, -0.3, -0.3 }, { -0.3,  0.3,  0.3 },
	{ -0.3,  0.3,  0.3 }, { -0.3, -0.3, -0.3 }, { -0.3, -0.3,  0.3 },
	{ -0.3,  0.3, -0.3 }, { -0.3,  0.3,  0.3 }, {  0.3,  0.3, -0.3 },
	{  0.3,  0.3, -0.3 }, { -0.3,  0.3,  0.3 }, {  0.3,  0.3,  0.3 },
	{ -0.3, -0.3,  0.3 }, { -0.3, -0.3, -0.3 }, {  0.3, -0.3,  0.3 },
	{  0.3, -0.3,  0.3 }, { -0.3, -0.3, -0.3 }, {  0.3, -0.3, -0.3 }
	};

// 面の法線データ
float	cube_fnor[TRIANGLE_NUMBER][3] = {
	{  0.0,  0.0,  1.0 }, {  0.0,  0.0,  1.0 },
	{  1.0,  0.0,  0.0 }, {  1.0,  0.0,  0.0 },
	{  0.0,  0.0, -1.0 }, {  0.0,  0.0, -1.0 },
	{ -1.0,  0.0,  0.0 }, { -1.0,  0.0,  0.0 },
	{  0.0,  1.0,  0.0 }, {  0.0,  1.0,  0.0 },
	{  0.0, -1.0,  0.0 }, {  0.0, -1.0,  0.0 }
	};

// テクスチャ座標
unsigned short cube_vtexi[TRIANGLE_NUMBER*3][2] = {
	{   0,   0 }, {   0,  63 }, {  63,   0 },
	{  63,   0 }, {   0,  63 }, {  63,  63 },	// 0 ROL1
	{  64,   0 }, {  64,  63 },	{ 127,   0 },
	{ 127,   0 }, {  64,  63 }, { 127,  63 },	// 1 ROL2
	{ 128,   0 }, { 128,  63 }, { 191,   0 },
	{ 191,   0 }, { 128,  63 }, { 191,  63 },	// 2 ROL3
	{ 192,   0 }, { 192,  63 },	{ 255,   0 },
	{ 255,   0 }, { 192,  63 }, { 255,  63 },	// 3 ROL4
	{   0,  64 }, {   0, 127 }, {  63,  64 },
	{  63,  64 }, {   0, 127 }, {  63, 127 },	// 4 ROL5
	{   0,   0 }, {   0,  63 },	{  63,   0 },
	{  63,   0 }, {   0,  63 }, {  63,  63 }	// 5 ROL1
	};

// テクスチャ座標2
unsigned short cube_vtexi2[TRIANGLE_NUMBER*3][2] = {
	{  64,  64 }, {  64, 127 }, { 127,  64 },	// TORI0
	{ 127,  64 }, {  64, 127 }, { 127, 127 },
	{ 192,  64 }, { 192, 127 },	{ 255,  64 },	// NEC
	{ 255,  64 }, { 192, 127 }, { 255, 127 },
	{ 192,  64 }, { 192, 127 },	{ 255,  64 },	// NEC
	{ 255,  64 }, { 192, 127 }, { 255, 127 },
	{ 128,  64 }, { 128, 127 },	{ 191,  64 },	// TORI1
	{ 191,  64 }, { 128, 127 }, { 191, 127 },
	{ 192,  64 }, { 192, 127 },	{ 255,  64 },	// NEC
	{ 255,  64 }, { 192, 127 }, { 255, 127 },
	{ 192,  64 }, { 192, 127 },	{ 255,  64 },	// NEC
	{ 255,  64 }, { 192, 127 }, { 255, 127 }
	};

// テクスチャ座標3
unsigned short cube_vtexi3[TRIANGLE_NUMBER*3][2] = {
	{ 128, 128 }, { 128, 191 }, { 191, 128 },	// FACE0
	{ 191, 128 }, { 128, 191 }, { 191, 191 },
	{ 192, 128 }, { 192, 191 },	{ 255, 128 },	// FACE1
	{ 255, 128 }, { 192, 191 }, { 255, 191 },
	{   0, 192 }, {   0, 255 }, {  63, 192 },	// FACE2
	{  63, 192 }, {   0, 255 }, {  63, 255 },
	{  64, 192 }, {  64, 255 },	{ 127, 192 },	// FACE3
	{ 127, 192 }, {  64, 255 }, { 127, 255 },
	{ 128, 192 }, { 128, 255 }, { 191, 192 },	// FACE4
	{ 191, 192 }, { 128, 255 }, { 191, 255 },
	{ 192, 192 }, { 192, 255 },	{ 255, 192 },	// FACE5
	{ 255, 192 }, { 192, 255 }, { 255, 255 }
	};

void InitSystem (void);
void InitScreen (void);
void AicLoad(unsigned short bank, unsigned char *filename);
void AcdLoad(unsigned char *filename);
void kingload(int bgnum, unsigned char *filename);

/*
 * メイン
 */
void
main()
	{
	short		vert[64][3];
	short		fnor[64][3];
	short		*outv = (short *)FARL_RESULT_REG0;
	int		cube_cnt[MAXCUBE];
	int		i, cnt;

	// 初期化
	InitSystem();
	InitScreen();
	FX73init();
	FX73_cmap_i3c6();
	FarlInit();

//	FarlSetMemReg( FARL_INTERRUPT_MASK_REG, FARL_INTERRUPT_AFL );
//	FarlSetPEControlReg( 0 );
	FarlSetPEICMaskReg( FARL_ICMASK_I3C6 );
	FarlSetTEControlReg( FARL_TE_ICM );
	FarlSetPEClearColorReg( 0x000 );

	KINGScreen(0);								// 画面モード16m色
	KINGDispOff();								// HuC6272 表示オフ
	KINGCylinder(KING_BG0,1);					// 茶筒モード
	KINGChangeSize0(DISP_NORMAL);				// 画面幅設定
	dispoff(bg | spr | rain | bg1 | bg2 | bg3);	// 他画面オフ
	dispon(bg | spr | bg0);						// 画面ON
	KINGCls(KING_BG0);							// 画面消去
	KINGDispOff();								// HuC6272 表示オン

	// テクスチャデータの読み込み
	AicLoad(0,"STEST.AIC");

	// 背景データの読み込み
	kingload(KING_BG0,"STEST.BIN");

	// パレットデータの読み込み
	AcdLoad("STEST.ACD");
	write_pallet_datas(0,colortable,512);

	// 背景表示ON
	KINGDispOn();

	FarlSetPETextureReg(0);
	FarlSetUVOffsetReg(0,0);

	// トライアングルリストの作成
	for ( i = 0; i < TRIANGLE_NUMBER; i++ )
		{
		vert[i*3+0][0]	= FarlFix1015( cube_vert[i*3+0][0] );
		vert[i*3+0][1]	= FarlFix1015( cube_vert[i*3+0][1] );
		vert[i*3+0][2]	= FarlFix1015( cube_vert[i*3+0][2] );

		vert[i*3+1][0]	= FarlFix1015( cube_vert[i*3+1][0] );
		vert[i*3+1][1]	= FarlFix1015( cube_vert[i*3+1][1] );
		vert[i*3+1][2]	= FarlFix1015( cube_vert[i*3+1][2] );

		vert[i*3+2][0]	= FarlFix1015( cube_vert[i*3+2][0] );
		vert[i*3+2][1]	= FarlFix1015( cube_vert[i*3+2][1] );
		vert[i*3+2][2]	= FarlFix1015( cube_vert[i*3+2][2] );

		fnor[i][0]	= FarlFix1015( cube_fnor[i][0] );
		fnor[i][1]	= FarlFix1015( cube_fnor[i][1] );
		fnor[i][2]	= FarlFix1015( cube_fnor[i][2] );
		}
	cube_cnt[0] = FarlDumpTriangleList( FARL_GTYPE_TX, TRIANGLE_NUMBER,
			(unsigned short *)vert, NULL,
					NULL, (unsigned short *)cube_vtexi, cube_buf[0] );
	cube_cnt[1] = FarlDumpTriangleList( FARL_GTYPE_TX, TRIANGLE_NUMBER,
			(unsigned short *)vert, NULL,
					NULL, (unsigned short *)cube_vtexi2, cube_buf[1] );
	cube_cnt[2] = FarlDumpTriangleList( FARL_GTYPE_TX, TRIANGLE_NUMBER,
			(unsigned short *)vert, NULL,
					NULL, (unsigned short *)cube_vtexi3, cube_buf[2] );

	cnt = 0;
	get_pad();	// DUMMY

	// メインループ
	while(1)
		{
		// 一時停止
		get_pad();
		if ( pad00.KD_TRG & KP_run )
			{
			while(1)
				{
				get_pad();
				if ( pad00.KD_TRG & KP_run ) break;
				}
			}

		// 1つ目
		FarlSetUnitMatrix187();
		FarlRotateX4x4M187( ( cnt / 3 ) % 3600 );
		FarlCopyDstToSrc();
		FarlTranslate4x4M187( 0x0050, 0x0000, 0x0000 );
		FarlCopyDstToSrc();
		FarlRotateY4x4M187( cnt % 3600 );
		FarlCopyDstToSrc();
		FarlTranslate4x4M187( 0x0000, 0x0000, 0xff80 );
		FarlCopyDstToSrc();
		FarlPerseZ4x4M187( 0xff80 );
		FarlCopyDstToObj();
		FarlSetPETextureReg(0);
		FarlWriteFifoHA(cube_buf[0], cube_cnt[0]);

		// 2つ目
		FarlSetUnitMatrix187();
		FarlRotateX4x4M187( ( cnt / 2 ) % 3600 );
		FarlCopyDstToSrc();
		FarlTranslate4x4M187( 0x0050, 0x0050, 0x0000 );
		FarlCopyDstToSrc();
		FarlRotateY4x4M187( cnt*2 % 3600 );
		FarlCopyDstToSrc();
		FarlTranslate4x4M187( 0x0000, 0x0000, 0xff80 );
		FarlCopyDstToSrc();
		FarlPerseZ4x4M187( 0xff80 );
		FarlCopyDstToObj();
		FarlSetPETextureReg(0);
		FarlWriteFifoHA(cube_buf[1], cube_cnt[1]);

		// 3つ目
		FarlSetUnitMatrix187();
		FarlRotateX4x4M187( cnt*2 % 3600 );
		FarlCopyDstToSrc();
		FarlTranslate4x4M187( 0x0050, -0x0050, 0x0000 );
		FarlCopyDstToSrc();
		FarlRotateY4x4M187( (cnt/2) % 3600 );
		FarlCopyDstToSrc();
		FarlTranslate4x4M187( 0x0000, 0x0000, 0xff80 );
		FarlCopyDstToSrc();

		FarlPerseZ4x4M187( 0xff80 );
		FarlCopyDstToObj();
		FarlSetPETextureReg(0);
		FarlWriteFifoHA(cube_buf[2], cube_cnt[2]);

		FarlSwapWindow();
		cnt += 20;
		}
	}

/*
 * 背景を読み込み表示する
 */
void
kingload(int bgnum, unsigned char *filename)
	{
	int	fh;

	// ファイル読込
	pio_putstr( "BG data loading..." );
	if ( (fh = pio_fopen(filename, "rb")) == -1 )
		{
		pio_putstr("ファイルが開けません。\n");
		return;
		}
	pio_fread(fh,122880,buf);
	pio_fclose(fh);
	KINGDispOff();
	KINGScreen(0);
	KINGCls(KING_BG0);
	KINGTrans(bgnum,buf,2);
	KINGDispOff();
	pio_putstr( "done.\n" );
	}

/*
 * AICファイルの読み込み
 */
void
AicLoad(unsigned short bank, unsigned char *filename)
	{
	int	fp, i, num;
	int	x,y;

	pio_putstr( "Sprite data loading..." );

	// 読み込み
	fp = pio_fopen(filename, "rb" );
	if ( fp == -1 )
		{
		pio_putstr( "\nCannot open AIC file.\n" );
		return;
		}
	i = pio_fread( fp, 4, (char *)( &num ) );
	if ( i < 4 )
		{
		pio_putstr( "\nAIC file read error.\n" );
		return;
		}
	i = pio_fread( fp, num, (char *)buf );
	if ( i < num )
		{
		pio_putstr( "\nAIC file read error.\n" );
		return;
		}
	FarlSetPETextureReg(bank);
	for ( i = 0; i < ( num / 2 ); i++ )
		{
		FarlWriteFifoH( buf[i] );
		}
	pio_putstr( "done.\n" );
	return;
	}

/*
 * ACDファイルの読み込み
 */
void
AcdLoad(unsigned char *filename)
	{
	int	fp;

	pio_putstr( "palette data loading..." );

	// 読み込み
	fp = pio_fopen(filename, "rb" );
	if ( fp == -1 )
		{
		pio_putstr( "\nCannot open ACD file.\n" );
		return;
		}
	// ヘッダを飛ばす(64 + 40byteのACDの場合)
	pio_fread( fp, 104, (unsigned char *)colortable );

	// パレットデータ読み込み
	pio_fread( fp, 1024, (unsigned char *)colortable );

	pio_putstr( "done.\n" );
	return;
	}

/*
 * システム初期化
 */
void
InitSystem()
	{
	irq_disable();
	cache_clear();
	cache_enable();
    set_irq_mask(
		BIT_IRQM_SIO | 
		BIT_IRQM_7A | 
		BIT_IRQM_7B |
		BIT_IRQM_KING |
		BIT_IRQM_KP |
		BIT_IRQM_EXT |
		BIT_IRQM_TMI |
		BIT_IRQM_AERR |
		0
		);

	set_irq_prio(IRQ_PRIOA, IRQ_KP);
	set_irq_vector(&int_pad, IRQ_LEVELA);

    reset_irq_mask(
//			BIT_IRQM_SIO | 
//			BIT_IRQM_7A | 
//			BIT_IRQM_7B |
//			BIT_IRQM_KING |
			BIT_IRQM_KP |
//			BIT_IRQM_EXT |
//			BIT_IRQM_TMI |
//			BIT_IRQM_AERR |
			0
		);

	set_irq_level(0x0007);
	irq_enable();
	init_get_pad();
	get_pad();
	}

/*
 * 画面初期化
 */
void
InitScreen()
	{
	int i;

	init_nt();
	init_70();
	dispon(bg | spr | bg0 | bg1 | bg2 | bg3 | rain );
	dispoff( /*bg | spr |*/ bg0 | bg1 | bg2 | bg3 | rain );
	set_nt_mode(interlace | inter_sync | mode_5M | mode_sp256 | mode_bg256);

	cel_off(bg);
	cel_off(spr);
	cel_off(bg0);
	cel_off(bg1);
	cel_off(bg2);
	cel_off(bg3);
	cel_off(rain);
	}

